﻿#region License
// Copyright 2009 Buu Nguyen (http://www.buunguyen.net/blog)
// 
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at 
// 
// http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License.
// 
// The latest version of this file can be found at http://www.codeplex.com/aspmvcvalidation
#endregion

using System;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace Mvc.Validation.Validators
{
    /// <summary>
    /// Logs an error if the string to validate is not between the specified range.
    /// The version of Enterprise Library works with <code>DateTime</code> type only.
    /// </summary>
    internal sealed class DateTimeValidator : ValueValidator
    {
        private readonly DateTime lowerBound;
        private readonly DateTime upperBound;

        public DateTimeValidator(DateTime lowerBound, DateTime upperBound, string messageTemplate)
			: base(messageTemplate, null, false)
        {
            this.lowerBound = lowerBound;
            this.upperBound = upperBound;
        }

        protected override void DoValidate(object objectToValidate,
			object currentTarget,
			string key,
			ValidationResults validationResults)
        {
            if (objectToValidate != null && !(objectToValidate is string))
                throw new ArgumentException("This validator can only be applied to string type");

            var stringValue = (string)objectToValidate;
            if (string.IsNullOrEmpty(stringValue))
                return;

            DateTime datetime;
            if (!DateTime.TryParse(stringValue, out datetime))
            {
                LogError(objectToValidate, validationResults, key, currentTarget);
            }
            else if (datetime < lowerBound || datetime > upperBound)
            {
                LogError(objectToValidate, validationResults, key, currentTarget);
			}
		}

        private void LogError(object objectToValidate, ValidationResults validationResults, string key, object currentTarget)
        {
            var msg = string.Format(MessageTemplate, lowerBound, upperBound);
            LogValidationResult(validationResults, msg, currentTarget, key);
        }

        protected override string DefaultNonNegatedMessageTemplate
        {
            get { return "Date must be between the specific range"; }
        }

        protected override string DefaultNegatedMessageTemplate
        {
            get { return null; }
        }
    }
}
